#ifndef _FUZZY_PID_H_
#define _FUZZY_PID_H_

#ifdef __cplusplus
extern "C" {    // 兼容C++编译器
#endif

/*--------------------------------- 基础头文件包含 -----------------------------*/
#include "math.h"
#include "stdlib.h"
#include "stdio.h"

// #include "fuzzy_pid_cfg.h"

/*--------------------------------- 布尔类型定义 -----------------------------*/
#ifndef bool
#define bool char
#endif
#ifndef false
#define false (char)0
#endif
#ifndef true
#define true (char)1
#endif


// 定义结构体
typedef struct {
    float Kp;
    float Ki;
    float Kd;
    float integral_limit;
    float dead_zone;
    float feed_forward;
} FuzzyPIDParams;

/*
0-高斯函数 1-钟形函数 2-S形函数 
3-梯形函数 5-Z形函数 4-三角函数
*/
typedef enum {
    Gaussmf,
    Gbellmf,
    Sigmf,
    Trapmf,
    Trimf,  
    Zmf
}MembershipFunction;


/*--------------------------------- 模糊量域定义 -----------------------------*/
// 定义模糊量化的等级数量（支持5/7/8等级划分）
enum quantity_fields {
    qf_small = 5,    // 5级量化（NB, NS, ZO, PS, PB）
    qf_middle = 7,   // 7级量化（NB,NM,NS,ZO,PS,PM,PB,推荐）
    qf_large = 8     // 8级量化（可自定义）
};
#define FUZZY_PID_QF_DEFAULT qf_middle  // 默认使用7级量化


/*--------------------------------- 控制模式设置 -----------------------------*/
#define FUZZY_PID_PARAMS_COUNT 7     // PID参数数组长度
#define FUZZY_PID_TORQUE_MODE 1          // 力矩控制模式
#define FUZZY_PID_POSTION_MODE 2        // 位置控制模式
#define FUZZY_PID_CONTROL_MODE FUZZY_PID_POSTION_MODE // 当前控制模式

/*--------------------------------- 模式相关参数 ----------------------------*/
#if FUZZY_PID_CONTROL_MODE == FUZZY_PID_POSTION_MODE
#   define MAX_ERROR 100.0f      // 位置模式误差范围±100
#   define MAX_DELTA_ERROR 100.0f
#else
#   define MAX_ERROR 12.0f       // 力矩模式误差范围±12
#   define MAX_DELTA_ERROR 12.0f
#endif

// pwm 范围设置
#define FUZZY_PID_MIN_PWM_OUTPUT 0
#define FUZZY_PID_MAX_PWM_OUTPUT 420
// 稳态
// 百分之 0.6 升降温因子
// 0.006*100  = 0.6
// ki * 积分项
#define FUZZY_PID_MIDDLE_PWM_OUTPUT  252

// #define FUZZY_PID_MAX_PWM_OUTPUT 1000
// #define FUZZY_PID_MIDDLE_PWM_OUTPUT 500  // 稳态


// #define FUZZY_PID_MIN_PWM_OUTPUT 0
// #define FUZZY_PID_MIDDLE_PWM_OUTPUT 500
// #define FUZZY_PID_MAX_PWM_OUTPUT 1000

/*--------------------------------- 模糊规则符号定义 --------------------------*/
// 7级量化规则集的列名称
#define NB -3   // 负大(Negative Big)
#define NM -2   // 负中(Negative Middle)
#define NS -1   // 负小(Negative Small)
#define ZO 0    // 零(Zero)
#define PS 1    // 正小(Positive Small)
#define PM 2    // 正中(Positive Middle)
#define PB 3    // 正大(Positive Big)

/*--------------------------------- 调试开关 ---------------------------------*/
// 可取消注释开启相应调试功能
// #define PID_DEBUG_PRINT        // 打印PID调试信息
// #define PID_DEBUG_ZONE          // 启用死区处理
// #define FUZZY_INTEGRAL_LIMIT     // 启用积分限幅

#define FUZZY_PID_DEBUG_PRINT  // 打印模糊PID调试信息

// #define FUZZY_PID_DEBUG_ZONE       // 模糊PID启用死区空间

//#define FUZZY_FUZZY_INTEGRAL_LIMIT  // 模糊PID启用积分限幅
//#define FUZZY_PID_RULE_BASE_DEEP_COPY // 模糊PID规则库深拷贝

/*--------------------------------- 模糊控制结构体 ----------------------------*/
// 定义模糊控制器的核心参数
typedef struct fuzzy{
    unsigned int input_num;   // 输入变量数量(例如：误差e和误差变化率de是2个输入)
    unsigned int output_num;  // 输出变量数量(例如：ΔKp,ΔKi,ΔKd是3个输出)
    unsigned int fo_type;     // 模糊算子类型：
                              // 0,1,2: 交算子(取小/代数积/有界积)
                              // 3,4,5: 并算子(取大/代数和/有界和) 
                              // >=6: 平衡算子
    unsigned int *mf_type;    // 隶属度函数类型数组(每个变量单独设置) 根据 input_num和output_num的 个数和 决定
    int *mf_params;           // 隶属度函数参数(例如三角形函数的a,b,c参数)
    unsigned int df_type;     // 解模糊方法：
                              // 0=重心法(默认), 1=最大隶属度法
    int *rule_base;           // 模糊规则库(二维规则表)
    float *output;            // 解模糊后的输出值(例如：[ΔKp, ΔKi, ΔKd])
}Fuzzy;

/*--------------------------------- PID控制结构体 ----------------------------*/
struct PID {
    /* 基础PID参数 */
    float kp;                 // 比例系数    
    float ki;                 // 积分系数
    float kd;                 // 微分系数
    
    /* 模糊参数调整限制 */
    float delta_kp_max;       // Kp的最大调整幅度（如±2.0）
    float delta_ki_max;       // Ki的最大调整幅度
    float delta_kd_max;       // Kd的最大调整幅度
    
    /* 运行时参数调整量 */
    float delta_kp;           // 当前的Kp调整值
    float delta_ki;           // 当前的Ki调整值
    float delta_kd;           // 当前的Kd调整值
    
    /* 误差相关参数 */
    float error_max;          // 误差范围上限（如±100）
    float delta_error_max;    // 误差变化率上限（如±100）
    float last_error;         // 上一次误差
    float current_error;      // 当前误差
    
    /* 积分限制 */
    float intergral;          // 积分累积值

    float intergral_limit;    // 积分限幅（抗饱和）
    
    /* 特殊控制参数 */
    float dead_zone;          // 死区阈值（误差小于此值时不做调节）         
    float feed_forward;       // 前馈补偿项
    
    /* 输出相关 */
    float output;             // 控制输出量（未限幅的原始值）
    int output_min_value;     // 最小输出值（如PWM的0）
    int output_middle_value;  // 中间输出基准值（常用于死区处理）
    int output_max_value;     // 最大输出值（如PWM的1000）
    
    /* 线性自适应参数（非模糊部分） */
    float linear_adaptive_kp; // 线性自适应增益
    
    /* 模糊控制关联 */
    Fuzzy *fuzzy_struct; // 绑定的模糊控制器结构体
};




// PWM输出范围定义

#ifndef FUZZY_PID_MIN_PWM_OUTPUT
#define FUZZY_PID_MIN_PWM_OUTPUT 0         

#endif

#ifndef FUZZY_PID_MIDDLE_PWM_OUTPUT
#define FUZZY_PID_MIDDLE_PWM_OUTPUT 500

#endif

#ifndef FUZZY_PID_MAX_PWM_OUTPUT
#define FUZZY_PID_MAX_PWM_OUTPUT 1000

#endif

/*--------------------------------- 函数声明 --------------------------------*/
// 模糊控制器初始化
Fuzzy *fuzzy_init(unsigned int input_num, unsigned int output_num);

// 模糊参数初始化（隶属度函数和规则库）
void fuzzy_params_init(Fuzzy *fuzzy_struct, unsigned int mf_type, unsigned int fo_type, unsigned int df_type,
                       int mf_params[], int rule_base[][FUZZY_PID_QF_DEFAULT]);

// 执行模糊控制计算
void fuzzy_control(float e, float de, Fuzzy *fuzzy_struct);

// PID初始化函数组（原始参数方式）
struct PID *raw_pid_init(float kp, float ki, float kd, float integral_limit, float dead_zone,
                         float feed_forward, float linear_adaptive_kp, float error_max, float delta_error_max,
                         int output_min_value, int output_middle_value, int output_max_value);

/**
 * 原始模糊PID控制器初始化（全参数版）
 * @param kp        比例系数基础值
 * @param ki        积分系数基础值
 * @param kd        微分系数基础值
 * @param integral_limit 积分限幅值
 * @param dead_zone      死区阈值
 * @param feed_forward   前馈系数
 * @param error_max      最大误差范围
 * @param delta_error_max 最大误差变化率
 * @param delta_kp_max   Kp最大调整幅度
 * @param delta_ki_max   Ki最大调整幅度
 * @param delta_kd_max   Kd最大调整幅度
 * @param mf_type       隶属度函数类型
 * @param fo_type       模糊算子类型
 * @param df_type       解模糊类型
 * @param mf_params     隶属度函数参数数组
 * @param rule_base     模糊规则库二维数组[output_num][FUZZY_PID_QF_DEFAULT*FUZZY_PID_QF_DEFAULT]
 * @param output_min_value 最小输出值
 * @param output_middle_value 中间基准值
 * @param output_max_value 最大输出值
 * @return PID控制器指针
 *
 * 注意：
 * - 该函数会创建并初始化关联的模糊控制器
 * - 规则库内存管理依赖FUZZY_PID_RULE_BASE_DEEP_COPY宏定义
 * - 输出值范围用于PWM等执行器限制
 */
struct PID *raw_fuzzy_pid_init(float kp, float ki, float kd, float integral_limit, float dead_zone,
                               float feed_forward, float error_max, float delta_error_max, float delta_kp_max,
                               float delta_ki_max, float delta_kd_max, unsigned int mf_type, unsigned int fo_type,
                               unsigned int df_type, int *mf_params, int rule_base[][FUZZY_PID_QF_DEFAULT],
                               int output_min_value, int output_middle_value, int output_max_value);

// PID初始化（参数数组方式）                     
struct PID *pid_init(float *params);

/**
 * 简化版模糊PID初始化
 * @param params       PID参数数组[6]:
 *                    [0]kp, [1]ki, [2]kd, [3]integral_limit,
 *                    [4]dead_zone, [5]feed_forward
 * @param delta_k      参数缩放因子（用于计算ΔK的最大调整量）
 * @param mf_type      隶属度函数类型
 * @param fo_type      模糊算子类型
                         0-2: 交算子(取小/代数积/有界积)
                         3-5: 并算子(取大/代数和/有界和) 
                         >=6: 平衡算子
 * @param df_type      解模糊类型
 * @param mf_params    隶属度函数参数数组
 * @param rule_base    模糊规则库二维数组
 * @return PID控制器指针
 *
 * @note
 * - 基于raw_fuzzy_pid_init()封装
 * - 使用预定义的误差范围和PWM输出范围
 * - 自动计算ΔK的缩放比例（原始参数/delta_k）
 */
struct PID *fuzzy_pid_init(float *params, float delta_k, unsigned int mf_type, unsigned int fo_type,
                           unsigned int df_type, int mf_params[], int rule_base[][FUZZY_PID_QF_DEFAULT]);


struct PID *fuzzy_pid_initParams(FuzzyPIDParams *params, float delta_k, unsigned int mf_type, unsigned int fo_type,
                           unsigned int df_type, int mf_params[], int rule_base[][FUZZY_PID_QF_DEFAULT]);

// PID控制器批量初始化                           
struct PID **pid_vector_init(float params[][FUZZY_PID_PARAMS_COUNT], unsigned int count);

/**
 * 批量初始化模糊PID控制器数组
 * @param params       PID参数二维数组[count][FUZZY_PID_PARAMS_COUNT]
 * @param delta_k      参数缩放因子（用于调整模糊输出幅度）
 * @param mf_type      隶属度函数类型
 * @param fo_type      模糊算子类型
 * @param df_type      解模糊类型
 * @param mf_params    隶属度函数参数数组
 * @param rule_base    模糊规则库三维数组[output_num][FUZZY_PID_QF_DEFAULT][FUZZY_PID_QF_DEFAULT]
 * @param count        要创建的控制器数量
 * @return PID控制器指针数组
 *
 * 内存管理：
 * - 返回的指针数组需要调用delete_pid_vector()释放
 * - 每个元素都是独立的PID控制器实例
 * - 规则库内存管理依赖FUZZY_PID_RULE_BASE_DEEP_COPY宏定义
 */
struct PID **
fuzzy_pid_vector_init(float params[][FUZZY_PID_PARAMS_COUNT], float delta_k, unsigned int mf_type, unsigned int fo_type,
                      unsigned int df_type, int *mf_params, int rule_base[][FUZZY_PID_QF_DEFAULT],
                      unsigned int count);

/*--------------------------------- 核心控制函数 -----------------------------*/
// 普通PID控制
float pid_control(float real, float idea, struct PID *pid);

// 模糊PID控制
float fuzzy_pid_control(float real, float idea, struct PID *pid);

/*--------------------------------- 执行器输出 -------------------------------*/
// 直接控制（无PID）
int direct_control(int zero_value, int offset_value, bool direct);

// 带PID的电机PWM输出
int pid_motor_pwd_output(float real, float idea, bool direct, struct PID *pid);

// 带模糊PID的电机PWM输出
int fuzzy_pid_motor_pwd_output(float real, float idea, bool direct, struct PID *pid);

/*--------------------------------- 资源清理 --------------------------------*/
void delete_pid(struct PID *pid);                 // 删除单个PID控制器
void delete_pid_vector(struct PID **pid_vector, unsigned int count); // 批量删除

#ifdef __cplusplus
}
#endif

#endif //_FUZZY_PID_H_
